package project

import (
	"context"
	"errors"
	dto "git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/dto/business_opportunity"
	"git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/repository/business_opportunity"
	pb "git.mycaigou.com/gfyx/micro-gfyx-api/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/business_opportunity"
	"git.myscrm.cn/golang/stark/v4"
)

type BuildingService struct {
	buildingRepo business_opportunity.BuildingRepositoryIface
}

func NewBuildingService(buildingRepo business_opportunity.BuildingRepositoryIface) BuildingServiceIface {
	return &BuildingService{buildingRepo: buildingRepo}
}

// BuildingList 在建项目列表
func (s *BuildingService) BuildingList(ctx context.Context, request *dto.BuildingListRequest) (*dto.BuildingListResponse, error) {
	data, err := s.buildingRepo.BuildingList(ctx, &pb.BuildingListRequest{
		Page:              request.Page,
		PageSize:          request.PageSize,
		Keyword:           request.Keyword,
		Area:              request.Area,
		CompanyArea:       request.CompanyArea,
		CompanyType:       request.CompanyType,
		CompanyLabel:      request.CompanyLabel,
		IsPriceGtAvg:      request.IsPriceGtAvg,
		PrjTypeNum:        request.PrjTypeNum,
		PrjPropertyNum:    request.PrjPropertyNum,
		StartDateStart:    request.StartDateStart,
		StartDateEnd:      request.StartDateEnd,
		CompleteDateStart: request.CompleteDateStart,
		CompleteDateEnd:   request.CompleteDateEnd,
		OrganizingCode:    request.OrganizingCode,
	})

	resp := &dto.BuildingListResponse{
		MaxNum: 5000,
		List:   make([]*dto.BuildingListItem, 0),
	}
	if err != nil {
		return resp, err
	}
	if data != nil {
		resp.Total = data.Total
		for _, item := range data.List {
			row := &dto.BuildingListItem{}
			row.Id = item.Id
			row.Address = item.Address
			row.City = item.City
			row.CityCode = item.CityCode
			row.StartDate = item.StartDate
			row.CompleteDate = item.CompleteDate
			row.PrjTypeNum = item.PrjTypeNum
			row.PrjPropertyNum = item.PrjPropertyNum
			row.PrjName = item.PrjName
			row.IsPriceGtAvg = item.IsPriceGtAvg
			row.BuildCorpName = item.BuildCorpName
			row.OrganizingCode = item.OrganizingCode
			row.CompanyTypeLabel = item.CompanyTypeLabel
			row.TopDeveloperName = item.TopDeveloperName
			row.TopOrganizingCode = item.TopOrganizingCode
			row.TopCompanyTypeLabel = item.TopCompanyTypeLabel
			row.ConscorpName = item.ConscorpName
			row.ConscorpOrganizingCode = item.ConscorpOrganizingCode
			row.County = item.County
			row.Province = item.Province
			row.ProvinceCode = item.ProvinceCode
			row.AllInvest = item.AllInvest
			row.AllArea = item.AllArea
			row.BuildCorpNameHL = item.BuildCorpName_HL
			row.PrjNameHL = item.PrjName_HL
			row.StartDateType = item.StartDateType

			resp.List = append(resp.List, row)
		}
	}
	return resp, nil
}

func (s *BuildingService) ExportBuildingList(ctx context.Context, request *dto.ExportBuildingListRequest) (*dto.ExportBuildingListResponse, error) {
	resp, err := s.buildingRepo.ExportBuildingList(ctx, &pb.ExportBuildingListRequest{
		Page:              request.Page,
		PageSize:          request.PageSize,
		Keyword:           request.Keyword,
		Area:              request.Area,
		CompanyArea:       request.CompanyArea,
		CompanyType:       request.CompanyType,
		CompanyLabel:      request.CompanyLabel,
		IsPriceGtAvg:      request.IsPriceGtAvg,
		PrjTypeNum:        request.PrjTypeNum,
		PrjPropertyNum:    request.PrjPropertyNum,
		StartDateStart:    request.StartDateStart,
		StartDateEnd:      request.StartDateEnd,
		CompleteDateStart: request.CompleteDateStart,
		CompleteDateEnd:   request.CompleteDateEnd,
	})
	if err != nil {
		return nil, err
	}
	if resp == nil {
		return nil, errors.New("导出失败")
	}

	return &dto.ExportBuildingListResponse{
		JobId: resp.JobId,
	}, nil
}

func (s *BuildingService) GetBuildingDetailBasic(ctx context.Context, request dto.GetBuildingDetailRequest) (*dto.GetBuildingDetailBasicResponse, error) {
	params := &pb.BuildingDetailRequest{
		Id: request.Id,
	}
	detailBasic, err := s.buildingRepo.GetBuildingDetailBasic(ctx, params)
	if err != nil {
		stark.Logger.Errorf(ctx, "GetBuildingDetailBasic request:%s , error: %v", request.Id, err)
		return nil, err
	}
	response := &dto.GetBuildingDetailBasicResponse{
		Id:                                 detailBasic.Id,
		Title:                              detailBasic.Title,
		ProjectNum:                         detailBasic.ProjectNum,
		ProjectProvinceNum:                 detailBasic.ProjectProvinceNum,
		BuildCorpName:                      detailBasic.BuildCorpName,
		BuildCorpOrganizingCode:            detailBasic.BuildCorpOrganizingCode,
		UpdateTime:                         detailBasic.UpdateTime,
		TotalInvestment:                    detailBasic.TotalInvestment,
		TotalArea:                          detailBasic.TotalArea,
		Province:                           detailBasic.Province,
		City:                               detailBasic.City,
		ProjectType:                        detailBasic.ProjectType,
		ProjectCategory:                    detailBasic.ProjectCategory,
		ConstructionNature:                 detailBasic.ConstructionNature,
		DataLevel:                          detailBasic.DataLevel,
		AdministrativeArea:                 detailBasic.AdministrativeArea,
		Address:                            detailBasic.Address,
		StartDate:                          detailBasic.StartDate,
		EndDate:                            detailBasic.EndDate,
		ProjectApprovalNum:                 detailBasic.ProjectApprovalNum,
		ProjectApprovalLevel:               detailBasic.ProjectApprovalLevel,
		ProjectApprovalAuthority:           detailBasic.ProjectApprovalAuthority,
		ProjectApprovalDate:                detailBasic.ProjectApprovalDate,
		FundingSource:                      detailBasic.FundingSource,
		StateOwnedCapitalContributionRatio: detailBasic.StateOwnedCapitalContributionRatio,
		IsKeyProject:                       detailBasic.IsKeyProject,
		ConstructionScale:                  detailBasic.ConstructionScale,
		IsPriceGtAvg:                       detailBasic.IsPriceGtAvg,
		OpptyStatus:                        detailBasic.OpptyStatus,
		RelatedCompany:                     make([]*dto.RelatedCompany, 0),
	}
	// 拼接公司
	for _, v := range detailBasic.RelatedCompany {
		labels := make([]string, 0)
		if v.Labels != nil {
			labels = v.Labels
		}
		response.RelatedCompany = append(response.RelatedCompany, &dto.RelatedCompany{
			CompanyName:       v.CompanyName,
			OrganizingCode:    v.OrganizingCode,
			TopCompanyName:    v.TopCompanyName,
			TopOrganizingCode: v.TopOrganizingCode,
			Role:              v.BusinessType,
			Labels:            labels,
		})
	}

	return response, nil
}

func (s *BuildingService) GetBuildingDetailTargetNum(ctx context.Context, request dto.GetBuildingDetailRequest) (*dto.GetBuildingDetailTargetNumResponse, error) {
	params := &pb.BuildingDetailRequest{
		Id: request.Id,
	}
	targets, err := s.buildingRepo.GetBuildingDetailTargetNum(ctx, params)
	if err != nil {
		stark.Logger.Errorf(ctx, "GetBuildingDetailTargetNum request:%s , error: %v", request.Id, err)
		return nil, err
	}
	return &dto.GetBuildingDetailTargetNumResponse{
		Bid:                  targets.Bid,
		Contract:             targets.Contract,
		WorkingDrawingAudit:  targets.WorkingDrawingAudit,
		ConstructionPermit:   targets.ConstructionPermit,
		CompletionAcceptance: targets.CompletionAcceptance,
		CompletionFiling:     targets.CompletionFiling,
		ParticipatingUnit:    targets.ParticipatingUnit,
		Contact:              targets.Contact,
	}, nil
}

func (s *BuildingService) GetBuildingDetailBidList(ctx context.Context, request dto.GetBuildingDetailRequest) (*dto.GetBuildingDetailBidListResponse, error) {
	params := &pb.BuildingDetailRequest{
		Id:       request.Id,
		Page:     request.Page,
		PageSize: request.PageSize,
	}
	bidList, err := s.buildingRepo.GetBuildingDetailBidList(ctx, params)
	if err != nil {
		stark.Logger.Errorf(ctx, "GetBuildingDetailBidList request:%s , error: %v", request.Id, err)
		return nil, err
	}
	response := &dto.GetBuildingDetailBidListResponse{
		Total: bidList.Total,
		List:  make([]*dto.GetBuildingDetailBidListItem, 0),
	}
	if bidList.List != nil && len(bidList.List) > 0 {
		for _, v := range bidList.List {
			response.List = append(response.List, &dto.GetBuildingDetailBidListItem{
				BidType:        v.BidType,
				Id:             v.Id,
				OrganizingCode: v.OrganizingCode,
				PersonName:     v.PersonName,
				ProjectId:      v.ProjectId,
				ProjectNum:     v.ProjectNum,
				TenderUnit:     v.TenderUnit,
				WinbidAmount:   v.WinbidAmount,
				WinbidDate:     v.WinbidDate,
			})
		}
	}

	return response, nil
}

func (s *BuildingService) GetBuildingDetailParticipatingUnits(ctx context.Context, request dto.GetBuildingDetailRequest) (*dto.GetBuildingDetailParticipatingUnitsResponse, error) {
	params := &pb.BuildingDetailRequest{
		Id:       request.Id,
		Page:     request.Page,
		PageSize: request.PageSize,
	}
	participatingUnits, err := s.buildingRepo.GetBuildingDetailParticipatingUnits(ctx, params)
	if err != nil {
		stark.Logger.Errorf(ctx, "GetBuildingDetailParticipatingUnits request:%s , error: %v", request.Id, err)
		return nil, err
	}
	response := &dto.GetBuildingDetailParticipatingUnitsResponse{
		Total: participatingUnits.Total,
		List:  make([]*dto.GetBuildingDetailParticipatingUnitsItem, 0),
	}

	if participatingUnits.List != nil && len(participatingUnits.List) > 0 {
		for _, v := range participatingUnits.List {
			response.List = append(response.List, &dto.GetBuildingDetailParticipatingUnitsItem{
				Id:             v.Id,
				ProjectId:      v.ProjectId,
				ProjectNum:     v.ProjectNum,
				UnitName:       v.UnitName,
				OrganizingCode: v.OrganizingCode,
				CompanyRole:    v.CompanyRole,
				PersonName:     v.PersonName,
				PersonPhone:    v.PersonPhone,
			})
		}
	}

	return response, nil
}

func (s *BuildingService) GetBuildingDetailContractList(ctx context.Context, request dto.GetBuildingDetailRequest) (*dto.GetBuildingDetailContractListResponse, error) {
	params := &pb.BuildingDetailRequest{
		Id:       request.Id,
		Page:     request.Page,
		PageSize: request.PageSize,
	}
	contractList, err := s.buildingRepo.GetBuildingDetailContractList(ctx, params)
	if err != nil {
		stark.Logger.Errorf(ctx, "GetBuildingDetailContractList request:%s , error: %v", request.Id, err)
		return nil, err
	}

	response := &dto.GetBuildingDetailContractListResponse{
		Total: contractList.Total,
		List:  make([]*dto.GetBuildingDetailContractListItem, 0),
	}

	if contractList.List != nil && len(contractList.List) > 0 {
		for _, v := range contractList.List {
			response.List = append(response.List, &dto.GetBuildingDetailContractListItem{
				ContractAmount:                    v.ContractAmount,
				ContractIssuingUnit:               v.ContractIssuingUnit,
				ContractIssuingUnitOrganizingCode: v.ContractIssuingUnitOrganizingCode,
				ContractType:                      v.ContractType,
				ContractingUnit:                   v.ContractingUnit,
				ContractingUnitOrganizingCode:     v.ContractingUnitOrganizingCode,
				Id:                                v.Id,
				ProjectId:                         v.ProjectId,
				ProjectNum:                        v.ProjectNum,
				SigningDate:                       v.SigningDate,
				UpdateTime:                        v.UpdateTime,
			})
		}
	}

	return response, nil
}

func (s *BuildingService) GetBuildingDetailWorkingDrawingAudit(ctx context.Context, request dto.GetBuildingDetailRequest) (*dto.GetBuildingDetailWorkingDrawingAuditResponse, error) {
	params := &pb.BuildingDetailRequest{
		Id:       request.Id,
		Page:     request.Page,
		PageSize: request.PageSize,
	}
	workingDrawingAudits, err := s.buildingRepo.GetBuildingDetailWorkingDrawingAudit(ctx, params)
	if err != nil {
		stark.Logger.Errorf(ctx, "GetBuildingDetailWorkingDrawingAudit request:%s , error: %v", request.Id, err)
		return nil, err
	}
	response := &dto.GetBuildingDetailWorkingDrawingAuditResponse{
		Total: workingDrawingAudits.Total,
		List:  make([]*dto.GetBuildingDetailWorkingDrawingAuditItem, 0),
	}

	if workingDrawingAudits.List != nil && len(workingDrawingAudits.List) > 0 {
		for _, v := range workingDrawingAudits.List {
			response.List = append(response.List, &dto.GetBuildingDetailWorkingDrawingAuditItem{
				Id:                             v.Id,
				IsCensorWfqtCount:              v.IsCensorWfqtCount,
				IsFirstPass:                    v.IsFirstPass,
				ProjectId:                      v.ProjectId,
				ProjectNum:                     v.ProjectNum,
				ReviewAgencyUnit:               v.ReviewAgencyUnit,
				ReviewAgencyUnitOrganizingCode: v.ReviewAgencyUnitOrganizingCode,
				ReviewCompletionDate:           v.ReviewCompletionDate,
				UpdateTime:                     v.UpdateTime,
			})
		}
	}
	return response, nil
}

func (s *BuildingService) GetBuildingDetailConstructionPermit(ctx context.Context, request dto.GetBuildingDetailRequest) (*dto.GetBuildingDetailConstructionPermitResponse, error) {
	params := &pb.BuildingDetailRequest{
		Id:       request.Id,
		Page:     request.Page,
		PageSize: request.PageSize,
	}
	constructionPermitList, err := s.buildingRepo.GetBuildingDetailConstructionPermit(ctx, params)
	if err != nil {
		stark.Logger.Errorf(ctx, "GetBuildingDetailConstructionPermit request:%s , error: %v", request.Id, err)
		return nil, err
	}
	response := &dto.GetBuildingDetailConstructionPermitResponse{
		Total: constructionPermitList.Total,
		List:  make([]*dto.GetBuildingDetailConstructionPermitItem, 0),
	}
	if constructionPermitList.List != nil && len(constructionPermitList.List) > 0 {
		for _, v := range constructionPermitList.List {
			response.List = append(response.List, &dto.GetBuildingDetailConstructionPermitItem{
				Area:                           v.Area,
				CertificateIssueDate:           v.CertificateIssueDate,
				ConstructionUnit:               v.ConstructionUnit,
				ConstructionUnitOrganizingCode: v.ConstructionUnitOrganizingCode,
				ContractAmount:                 v.ContractAmount,
				Id:                             v.Id,
				ProjectId:                      v.ProjectId,
				ProjectNum:                     v.ProjectNum,
				SupervisionUnit:                v.SupervisionUnit,
				SupervisionUnitOrganizingCode:  v.SupervisionUnitOrganizingCode,
			})
		}
	}

	return response, nil
}

func (s *BuildingService) GetBuildingDetailCompletionFiling(ctx context.Context, request dto.GetBuildingDetailRequest) (*dto.GetBuildingDetailCompletionFilingResponse, error) {
	params := &pb.BuildingDetailRequest{
		Id:       request.Id,
		Page:     request.Page,
		PageSize: request.PageSize,
	}
	constructionPermitList, err := s.buildingRepo.GetBuildingDetailCompletionFiling(ctx, params)
	if err != nil {
		stark.Logger.Errorf(ctx, "GetBuildingDetailCompletionFiling request:%s , error: %v", request.Id, err)
		return nil, err
	}
	response := &dto.GetBuildingDetailCompletionFilingResponse{
		Total: constructionPermitList.Total,
		List:  make([]*dto.GetBuildingDetailCompletionFilingItem, 0),
	}
	if constructionPermitList.List != nil && len(constructionPermitList.List) > 0 {
		for _, v := range constructionPermitList.List {
			response.List = append(response.List, &dto.GetBuildingDetailCompletionFilingItem{
				ActualConstructionScale: v.ActualConstructionScale,
				ActualCost:              v.ActualCost,
				ActualStartDate:         v.ActualStartDate,
				FilingDate:              v.FilingDate,
				Id:                      v.Id,
				ProjectId:               v.ProjectId,
				ProjectNum:              v.ProjectNum,
				UpdateTime:              v.UpdateTime,
			})
		}
	}
	return response, nil
}
